package com.las.nogu.web;

import com.las.bot.common.Constant;
import com.las.utils.mirai.CmdUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@ServerEndpoint("/osuchat/{id}")
public class OsuWebSocket {

    private final Log log = LogFactory.getLog(OsuWebSocket.class);


    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    private Session session;

    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。
    //虽然@Component默认是单例模式的，但springboot还是会为每个websocket连接初始化一个bean，所以可以用一个静态set保存起来。
    //  注：底下WebSocket是当前类名
    private static CopyOnWriteArraySet<OsuWebSocket> webSockets = new CopyOnWriteArraySet<>();
    // 用来存在线连接数
    private static Map<String, Session> sessionPool = new HashMap<>();

    /**
     * 链接成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "id") String id) {
        try {
            this.session = session;
            webSockets.add(this);
            sessionPool.put(id, session);
            log.info("【websocket消息】有新的连接，总数为:" + webSockets.size());
        } catch (Exception ignored) {
        }
    }

    /**
     * 链接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        try {
            webSockets.remove(this);
            log.info("【websocket消息】连接断开，总数为:" + webSockets.size());
        } catch (Exception ignored) {
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     */
    @OnMessage
    public void onMessage(String message) {
        log.info("【websocket消息】收到OSU客户端消息:" + message);
        // 前期暂时不做安全校验，后续必须要弄
        // 下一步将OSU用户的信息，以QQ机器人代理人身份发送
//        try {
//            String[] split = message.split("#");
//            if (split.length == 2) {
//                long gId = Long.parseLong(split[0]);
//                StringBuilder sb = new StringBuilder();
//                sb.append("来自90后蠢狼大叔发送消息：").append("\n");
//                sb.append(split[1].trim());
//                CmdUtil.sendMessage(sb.toString(), 0L, gId, Constant.MESSAGE_TYPE_GROUP);
//            }
//        } catch (Exception e) {
//            log.error("OSU消息错误：" + e.toString());
//        }
    }

    /**
     * 发送错误时的处理
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误,原因:" + error.getMessage());
    }


    // 此为广播消息
    public void sendAllMessage(String message) {
        log.info("【websocket消息】广播消息:" + message);
        for (OsuWebSocket webSocket : webSockets) {
            try {
                if (webSocket.session.isOpen()) {
                    webSocket.session.getAsyncRemote().sendText(message);
                }
            } catch (Exception ignored) {
            }
        }
    }

    // 此为单点消息
    public void sendOneMessage(String id, String message) {
        Session session = sessionPool.get(id);
        if (session != null && session.isOpen()) {
            try {
                log.info("【websocket消息】 单点消息:" + message);
                session.getAsyncRemote().sendText(message);
            } catch (Exception ignored) {

            }
        }
    }

}
